package org.arch_learn.io.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class NettyServer {
    public static void main(String[] args) throws InterruptedException {
        //1.创建bossGroup线程组，处理网络连接事件(主线程组设置2个线程,不设置的话默认为处理器线程数）
        EventLoopGroup bossGroup = new NioEventLoopGroup(2);
        //2.创建workGroup线程组，处理网络读写事件(从线程组设置10个线程,不设置的话默认为处理器线程数 * 2）
        EventLoopGroup workGroup = new NioEventLoopGroup(10);
        //3.创建服务端启动助手
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        //4.设置bossGroup线程组和workGroup线程组
        serverBootstrap.group(bossGroup, workGroup)
                //5.设置服务端通道（serverSocketChannel)为NIO
                .channel(NioServerSocketChannel.class)
                //6.bossGroup参数设置(设置连接等待个数)
                .option(ChannelOption.SO_BACKLOG, 128)
                //7.workGroup参数设置(设置活跃状态)
                .childOption(ChannelOption.SO_KEEPALIVE, Boolean.TRUE)
                //8.创建一个通道初始化对象
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel channel) throws Exception {
                        //9.向pipeline中添加自定义业务处理handler
                        ChannelPipeline pipeline = channel.pipeline();
                        //添加解码器
                        //pipeline.addLast("messageDecoder", new MessageDecoder());
                        //添加编码器
                        //pipeline.addLast("messageEncoder", new MessageEncoder());
                        //添加编解码器
                        pipeline.addLast(new MessageCodec());
                        pipeline.addLast(new NettyServerHandler());

                    }
                });
        //10.启动服务端并绑定端口，同时将异步改成同步
        ChannelFuture channelFuture = serverBootstrap.bind(9999);
//                .sync();
        channelFuture.addListener((ChannelFutureListener) channelFuture1 -> {
            if (channelFuture1.isSuccess()) {
                System.out.println("端口绑定成功！");
            } else {
                System.out.println("端口绑定失败！");
            }
        });
        System.out.println("Netty服务端启动成功！");
        //11.关闭通道(并不是真正意义上的关闭，而是监听通道关闭的状态)和关闭连接池
        channelFuture.channel().closeFuture().sync();
        //有通道关闭，才会执行下面代码，因为上一行代码的sync方法使线程阻塞在上一行了。
        bossGroup.shutdownGracefully();
        workGroup.shutdownGracefully();
    }
}
